package com.aop.service.impl;

import com.aop.entities.Payment;
import com.aop.mapper.PaymentMapper;
import com.aop.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.UUID;

/**
 * @Author: tgy
 * @Date: 2020-08-11 18:45
 */
@Service
public class OrderServiceImpl implements OrderService, Serializable {

    @Resource
    private PaymentMapper paymentMapper;

    @Override
    public String pay(String orderId) {

        return UUID.randomUUID().toString();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertPayment() {

        Payment payment = new Payment();

        payment.setSerial(UUID.randomUUID().toString());

        paymentMapper.insert(payment);

//        int i = 10 / 0;

    }

    /**
     * 默认的回滚异常必须是 RuntimeException 或者 Error 的子类，开发中把 rollbackFor设置为 Exception
     *
     * public boolean rollbackOn(Throwable ex) {
     * 		return (ex instanceof RuntimeException || ex instanceof Error);
     * }
     *
     * 事务的属性
     *
     * 1.隔离性
     * 使用默认值，默认值根据数据库来进行选择
     *  - read_uncommit
     *  - read_commited 脏读： 读到了另一个事务没有提及的数据
     *  - repeat_read   不可重复读: 读到了另一个事务已经提交的数据
     *  - serializable  幻读: 对表整体操作，另一个事务进行了insert操作，当前事务对表整体操作前后不一致。
     *
     *
     * 2.传播性
     *
     *  Required : 有事务就事务，没有就创建 使用在 增删改方法中
     *  Supports: 有事务就用当前事务，没有也不创建事务 推荐使用在 查询方法中
     *  Require_New: 当前有事务挂起事务，在当前方法中创建一个新的事务，用作当前方法的事务， 推荐使用在 日志记录中
     *
     * 3.超时
     * 默认获取数据库的超时时间
     * 查询设置成只读
     *
     * 4. readOnly
     *
     * 4.rollback
     *
     * 5. norollback
     *
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public Payment insertPayment(Integer type) throws Exception {



        Payment payment = new Payment();
        payment.setSerial(UUID.randomUUID().toString());

        paymentMapper.insert(payment);

        if (type == 1){

            throw new Exception("哈哈");
        }

        return payment;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePayment(Payment payment) {

        if (payment.getId() == null){

            return false;
        }


        Payment savePayment = paymentMapper.selectById(payment.getId());

        if (savePayment == null){

            return false;
        }

        payment.setVersion(savePayment.getVersion());

        UpdateWrapper<Payment> objectUpdateWrapper = new UpdateWrapper<>();

        objectUpdateWrapper
                .set(!StringUtils.isEmpty(payment.getSerial()),"serial",payment.getSerial());

//        System.out.println(objectUpdateWrapper.getSqlSet());

//        int updateResult = paymentMapper.updatePayment(payment, payment.getVersion());
//        int updateResult = paymentMapper.updateById(payment);
        int updateResult = paymentMapper.updatePayment(payment);

        return updateResult > 0;
    }
}
